#ifndef VPD_SYSTEM_H
#define VPD_SYSTEM_H
#include <stdio.h>
#include <stdlib.h>
#include "data_struct.h"
#include "vpdCheckMessage.h"

#ifndef NO_FPGA_SDK_ENABLE
    #include "user_sound_module.h"
    #include "FreeRTOS.h"
    #include "task.h"
#else
    #include "no_fpga_head.h"
#endif
//#pragma pack(1)
typedef struct  VPD_INFO
{
    resIdentification idInfo;

}vpdInfo;
typedef struct VPD_MSG_BUF
{
    char buf[64];
    int  len;
}vpdMsgBuf;
typedef struct VPD_COE_BUF
{
	uint8_t id;
	uint8_t max;
	uint8_t index;
	float val[64];

}vpdCoeBuf;
typedef struct VPD_MIC_MAP
{
	uint8_t max;
	uint8_t index;
	uint8_t val[256];
}vpdMicMap;
typedef struct VPD_FW_INFO
{
    char        *buf;
    uint64_t    index;
    uint64_t    length;
    uint16_t    checkSum;
    uint8_t     upFlag;
    uint8_t     upPercent;
    //   char        version[32];
}vpdFwInfo;
typedef struct OBJ_READ_RES
{
    uint32_t  len;
    resReadObjs  obj;
}objReadRes;
typedef struct STATUS_RES
{
    uint32_t  len;
    resStatus status;
}statusRes;
typedef struct OBJ_RAW_DATA
{
    uint32_t    len;
	uint32_t	chs;
	uint32_t	size;
    objStRawData obj;
}objRawdata;
typedef struct OBJ_RAW_FFT
{
    uint32_t    len;        
    objStRawFFT obj;    
}objRawFFT;
struct VPD_PARAMETER
{
    uint32_t    sampleRate;     
    double      dt;             
    uint32_t    maxChannels;    
    uint32_t    curChannels;    

    uint32_t    onedataLen;    
    uint8_t     onedataSize;    

    uint32_t    rawfftLen;     
    uint8_t     rawfftSize;     
    uint32_t    fftFreqMin;     
    uint32_t    fftFreqMax;     
    uint32_t    fftDf;           


    uint32_t    onefftLen;     
    uint8_t     onefftSize;     
};
typedef struct FPGA_SETTING
{
	uint32_t	vpdOpMode;		//
	uint32_t	vpdOutMode;		//
	uint32_t	vpdSampleRate;
	uint32_t	vpdOverlap;
	uint32_t	vpdMask[8];
}fpgaSetting;

typedef struct VPD_SETTINGS
{
	uint32_t	sampleRate;
	uint32_t	micIndex;
	uint32_t	freqMin;
	uint32_t	freqMax;
	uint32_t	distance;
	uint32_t	lightOn;
	uint32_t	beamFPS;
	uint32_t	imgFPS;
	uint32_t	imgWidth;
	uint32_t	imgHeight;
	uint32_t	fftFps;
}vpdSettings;
#define	SET_MASK_OPMODE  (1<<0)
#define SET_MASK_OUTMODE	(1<<1)
#define	SET_MASK_SAMPLERATE	(1<<2)
#define SET_MASK_OVERLAP	(1<<3)
#define SET_MASK_MG0		(1<<4)
#define SET_MASK_MG1		(1<<5)
#define SET_MASK_MG2		(1<<6)
#define SET_MASK_MG3		(1<<7)
#define SET_MASK_MG4		(1<<8)
#define SET_MASK_MG5		(1<<9)
#define SET_MASK_MG6		(1<<10)
#define SET_MASK_MG7		(1<<11)
#define SET_MASK_ALL		0xFFFF

struct FFT_RANGE_SET
{
    uint32_t    FFT_FREQ_MIN;
    uint32_t    FFT_FREQ_MAX;
    uint32_t    FFT_FREQ_ORGIN;
    uint32_t    FFT_FREQ_LEN;
};
#pragma pack()

typedef struct VPD_SYSTEM
{

   struct VPD_PARAMETER parameter;
   enum DEVICE_STATUS  devNeedStatus;
   enum DEVICE_STATUS  devCurStatus;
   enum DEVICE_SUB_STATUS devSubStatus;
   uint8_t      vpdStatus;      //  DEVICE_STATUS
   vpdFwInfo    fwInfo;
   uint8_t      vpdFirstCon;        //First Connect
   struct TCP_SEND_MASK  tcpSendMask;
   struct OBJ_HEAD_LENGTHS headLen;
  // struct FFT_RANGE_SET   fftRange;
   vpdSettings	mSettings;
   uint32_t     rawdataBufferSize;
   uint32_t     onedataBufferSize;
   uint32_t     rawfftBufferSize;
   uint32_t     onefftBufferSize;
   objStRawData *p_globalStRawData;     //rawdata head
   objStRawFFT  *p_globalStRawFFT;      //rawfft head
   objStJpeg    *p_globalStJpeg;
   objStAcoustic *p_globalStAcoustic;
   objStOneFFT   *p_globalStOneFFT;
   objStOneData  *p_globalStOneData;
   objStCommonStatus	*p_globalStcommonStatus;
   objStReplyMessage    *p_globalStReplyMessge;
   char                  tempMsg[MAX_MSG_BUFFER];
   uint64_t      m_rawdataTs;       // for rawdata ts
   uint64_t      m_rawfftTs;            //rawfft ts
   u8			 m_heartRateFlag;
  // vpdController *p_vpdCtrl;

    int      socketFd;      
    vpdMsgBuf   m_restBuf;
    vpdCoeBuf	m_coeBuf;
    vpdMicMap	m_micMap;
    VPD_MESSAGE *pVpdMsg;
    int      bufPos;
    TickType_t	xStart;


    uint8_t  invokeId;
    uint32_t  status;
    uint64_t  timestamps;
    uint64_t  frameCnts;
    uint32_t  frameDt;
    uint8_t   fpgaErr;

    resIdentification *idInfo;
    objReadRes  objRR;      //obj read response;
    statusRes   statusR;    //status response

    int (*sendData)(void *sys,char *buf,int len);
    void (*sendReplyMessage)(void *sys,char *msg);
//
    void (*updateVPDParameters)(void *sys,struct VPD_PARAMETER *);



    void (*parseAndReponseMessage)(void *sys,char *buf,int len);
    void (*generateRawData)(void *sys,uint32_t len);
    void (*generateFFTData)(void *s,uint32_t len);
    void  (*generateJpegData)(void *sys,uint32_t len);
    void (*generateAcousData)(void *sys,uint32_t len);
    void (*generateOneData)(void *sys,uint32_t len);
    void (*generateOneFFT)(void *sys,uint32_t len);
    void (* generateObjReadResponse)(void *sys,uint8_t objID);
//some function
    void *(*generateIdResponse)(void *);
    char * (*generateObjRResponse)(void *,int type,int *size);
    char * (*generateObjWResponse)(void *,int type,int *size);
    void (*processCmd)(void *,int cmd);
    void (*processData)(void *);
    int (*setSocketFd)(void *,int sd);		//set the socket fd
    void (*vpdSystemInit)(void *);
    void (*resetVPDStatus)(void *);
   // void *  (*pStatusResponse)(uint8_t type,uint8_t invokeId);

}vpdSystem;
resIdentification * vpd_indentification_init();
vpdSystem * createVpdSystem();
//uint8_t    parseBuffer(char *buf,int len);
extern vpdSystem *vpdSys;
uint16_t crc16_ccitt(uint8_t *data, size_t length);
#endif // VPD_SYSTEM_H
